package org.groupg.practice.data;

import jdk.jfr.Event;
import jdk.jfr.Label;
import jdk.jfr.Description;
import jdk.jfr.Category;

public class PreciseMemoryTracker {

    @Label("内存分配")
    @Description("跟踪数据结构的内存分配")
    @Category("内存")
    static class MemoryAllocationEvent extends Event {
        String dataStructure;
        long objectCount;
        long estimatedBytes;
        double bytesPerObject;
    }

    /**
     * 使用JOL (Java Object Layout) 精确测量对象大小
     * 需要添加依赖: org.openjdk.jol:jol-core
     */
    public static void analyzeMemoryUsage(Object obj, String description) {
        try {
            // 使用JOL进行精确分析
            System.out.println("=== " + description + " ===");

            MemoryAllocationEvent event = new MemoryAllocationEvent();
            event.dataStructure = description;
            event.begin();

            // 估算对象图大小
            long size = estimateObjectSize(obj);
            event.estimatedBytes = size;

            event.commit();

            System.out.printf("估算内存: %,d bytes (%.2f MB)%n",
                size, size / (1024.0 * 1024.0));

        } catch (Exception e) {
            System.err.println("内存分析失败: " + e.getMessage());
        }
    }

    private static long estimateObjectSize(Object obj) {
        // 简化估算，实际应该使用JOL
        if (obj instanceof it.unimi.dsi.fastutil.ints.IntArrayList) {
            it.unimi.dsi.fastutil.ints.IntArrayList list =
                (it.unimi.dsi.fastutil.ints.IntArrayList) obj;
            return 24 + (long) list.size() * 4; // 对象头 + 数据
        }
        // 其他类型的估算...
        return 0;
    }

    /**
     * 强制GC并获取内存快照
     */
    public static void memorySnapshot(String point) {
        Runtime runtime = Runtime.getRuntime();
        for (int i = 0; i < 3; i++) {
            System.gc();
            try { Thread.sleep(100); } catch (InterruptedException e) {}
        }

        long used = runtime.totalMemory() - runtime.freeMemory();
        System.out.printf("[%s] 内存使用: %,d MB%n",
            point, used / (1024 * 1024));
    }
}